const props = {
  code: {
    type: String
  }
}
export default defineComponent({
  name: 'Grapverif',
  props,
  emits: ['update:code'],
  setup(props, context) {
    const domRef = ref()
    const imgCode = ref('')

    const getImgCode = () => {
      if (!domRef.value) return
      imgCode.value = draw(domRef.value, 120, 40)
    }

    const setImgCode = (code?: string) => {
      if (!domRef.value) return
      draw(domRef.value, 120, 40, code)
    }

    context.expose({ getImgCode })

    watch(imgCode, newValue => context.emit('update:code', newValue))

    onMounted(() => (props.code ? setImgCode(props.code) : getImgCode()))

    return () => {
      return <canvas ref={domRef} onClick={getImgCode} />
    }
  }
})

const randomNum = (min: number, max: number) => Math.floor(Math.random() * (max - min) + min)

const randomColor = (min: number, max: number) => {
  const r = randomNum(min, max)
  const g = randomNum(min, max)
  const b = randomNum(min, max)
  return `rgb(${r},${g},${b})`
}

const drawCode = (ctx: CanvasRenderingContext2D, i: number, text: string) => {
  const fontSize = randomNum(18, 41)
  const deg = randomNum(-30, 30)
  ctx.font = `${fontSize}px Simhei`
  ctx.textBaseline = 'top'
  ctx.fillStyle = randomColor(80, 150)
  ctx.save()
  ctx.translate(30 * i + 15, 15)
  ctx.rotate((deg * Math.PI) / 180)
  ctx.fillText(text, -15 + 5, -15)
  ctx.restore()
  return ctx
}
const draw = (dom: HTMLCanvasElement, width: number, height: number, imgCode = '') => {
  const NUMBER_STRING = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'

  dom.height = height
  dom.width = width

  const ctx = dom.getContext('2d')
  if (!ctx) return imgCode
  ctx.fillStyle = randomColor(180, 230)
  ctx.fillRect(0, 0, width, height)

  /* 绘画 */
  if (imgCode) {
    for (let i = 0; i < 4; i++) {
      drawCode(ctx, i, imgCode[i])
    }
  } else {
    for (let i = 0; i < 4; i++) {
      const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)]
      imgCode += text
      drawCode(ctx, i, text)
    }
  }

  /* 噪线 */
  for (let i = 0; i < 5; i++) {
    ctx.beginPath()
    ctx.moveTo(randomNum(0, width), randomNum(0, height))
    ctx.lineTo(randomNum(0, width), randomNum(0, height))
    ctx.strokeStyle = randomColor(180, 230)
    ctx.closePath()
    ctx.stroke()
  }

  /* 噪点 */
  for (let i = 0; i < 41; i += 1) {
    ctx.beginPath()
    ctx.arc(randomNum(0, width), randomNum(0, height), 1, 0, 2 * Math.PI)
    ctx.closePath()
    ctx.fillStyle = randomColor(150, 200)
    ctx.fill()
  }

  return imgCode
}
